import std.stdio: writefln;
import derelict.sdl.sdl;

struct Color{
	union{
		struct{
			float r, g, b;
		}
		struct{
			float R, G, B;
		}
		float[3] col;
	}

	static Color opCall(float r, float g, float b){
		Color col;
		col.r = r;
		col.g = g;
		col.b = b;
		return col;
	}

	static Color opCall(uint r, uint g, uint b){
		Color col;
		col.r = r / 255.f;
		col.g = g / 255.f;
		col.b = b / 255.f;
		return col;
	}

	static Color opCall(uint c){
		Color col;
		col.b = (c % 0x100) / 255.f;
		c /= 0x100;
		col.g = (c % 0x100) / 255.f;
		c /= 0x100;
		col.r = c / 255.f;
		return col;
	}

	static Color hsvToRgb(float h, float s, float v){
		Color col;
		int i;
		float f, p, q, t;

	if( s == 0 ) {
		// achromatic (grey)
		col.r = col.g = col.b = v;
		return col;
	}

	h /= 60;			// sector 0 to 5
	i = cast(int)h;
	f = h - i;			// factorial part of h
	p = v * ( 1 - s );
	q = v * ( 1 - s * f );
	t = v * ( 1 - s * ( 1 - f ) );

	switch( i ) {
		case 0:
			col.r = v;
			col.g = t;
			col.b = p;
			break;
		case 1:
			col.r = q;
			col.g = v;
			col.b = p;
			break;
		case 2:
			col.r = p;
			col.g = v;
			col.b = t;
			break;
		case 3:
			col.r = p;
			col.g = q;
			col.b = v;
			break;
		case 4:
			col.r = t;
			col.g = p;
			col.b = v;
			break;
		default:		// case 5:
			col.r = v;
			col.g = p;
			col.b = q;
			break;
	}

		return col;
	}

	static Color black(){
		return Color(.0, .0, .0);
	}

	uint ui(){
		return 0x010000 * cast(uint)(255 * r) + 0x000100 * cast(uint)(255 * g) + cast(uint)(255 * b);
	}

	Color dup(){
		return Color(r, g, b);
	}

	Color normalize(){
		float max = 1.f;
		foreach(c;col)
			if(c > max) max = c;
		r /= max;
		g /= max;
		b /= max;
		return *this;
	}

	Color opMul(float f){
		Color col;
		col.r = r * f;
		col.g = g * f;
		col.b = b * f;
		col.normalize();
		return col;
	}

	Color opAdd(Color c){
		Color col;
		col.r = r + c.r;
		col.g = g + c.g;
		col.b = b + c.b;
		col.normalize();
		return col;
	}

}

alias Color color;
